home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 …ember: Reference Library / Apple Developer Reference Library (December 1999) (Disk 1).iso / pc / technical documentation / develop / develop issue 26 / develop issue 26 code / wide (64 bit) library / sources / wide.a < prev    next >
Encoding:
Text File  |  1996-07-18  |  6.6 KB  |  224 lines

  1. ;**********************************************************
  2. ;
  3. ;    Wide.a
  4. ;
  5. ;    Author:
  6. ;        Terry Teague
  7. ;        based on work by Dale Semchishen, 1996
  8. ;
  9. ;    Description:
  10. ;        A 64 bit integer library for the 680x0 and PowerPC processors
  11. ;
  12. ;        While this library is self-initializing you can choose
  13. ;        to call WideInit() during application startup so that
  14. ;        the first time you call a math routine it does not incur
  15. ;        the extra time required for initialization.
  16. ;
  17. ;        Most of the 64 bit routines in this library are available in
  18. ;        QuickDraw GX or on the PowerPC. On the 680x0 if you include
  19. ;        <GXTypes.h> or <GXMath.h> before "Wide.h" and compile this library,
  20. ;        the QuickDraw GX traps will be used instead of the routines
  21. ;        marked with "(gx)".
  22. ;
  23. ;        This file implements the 68K assembly language routines for MPW
  24. ;
  25. ;    Global functions:
  26. ;        WideInit()            - Initialize the Wide library (optional)
  27. ;
  28. ;        WideAdd()              - (gx) Add two 64 bit ints
  29. ;        WideAdd32()            -      Add 32 bits to a 64 bit int
  30. ;        WideAssign32()        -      Assign 32 bits to 64 bit int
  31. ;        WideBitShift()        -      Shift a 64 bit number
  32. ;        WideCompare()        - (gx) Compare two 64 bits ints
  33. ;        WideDivide()        - (gx) Divide 32 bit int into 64 bit int with a 32 bit result
  34. ;        WideMultiply()        - (gx) Multiply two 32 bits ints for a 64 bit result
  35. ;        WideNegate()        - (gx) Negative value of a 64 bit int
  36. ;        WideScale()            - (gx) Highest order nonzero bit in a 64 bit number
  37. ;        WideShift()            - (gx) Shift a 64 bit number and round up
  38. ;        WideSquareRoot()    - (gx) return 32 bit square root of an unsigned 64 bit number
  39. ;        WideSubtract32()    -      Subtract 32 bits from a 64 bit int
  40. ;        WideSubtract()        - (gx) Subtract a 64 bits int from a 64 bit int
  41. ;        WideToDecStr()        -      Convert 64 bit int to a SANE 'decimal' string
  42. ;        WideWideDivide()    - (gx) Divide 32 bit int into 64 bit int with a 64 bit result
  43. ;
  44. ;    Note:
  45. ;        This library has been compiled under the following
  46. ;        development systems:
  47. ;             - Symantec C 68K 7.0.4
  48. ;             - CodeWarrior 6 Lite (68K and PPC)
  49. ;             - CodeWarrior 9 (68K and PPC) - Terry Teague
  50. ;            - MPW 3.3.1 (MPWC 68K and PPCC PPC) - Terry Teague
  51. ;            - MPW 3.4.1 (SC 68K and MrC PPC) - Terry Teague
  52. ;
  53. ;**********************************************************
  54.  
  55.     CASE        OBJ
  56.  
  57.     include 'ToolUtils.a'
  58.  
  59.     IF            ( &FINDSYM(&SYSGLOBAL,'MACSBUG') = 1 ) THEN 
  60.     ;◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
  61.     ;    Macros for defining MacsBug procedure name / constants
  62.     ;◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
  63.  
  64.     MACRO
  65.     M_ProcName    &procedure_name
  66.     
  67.         STRING    PASCAL
  68.         dc.b    $80, &procedure_name
  69.         ALIGN    2
  70.         dc.w    $0000
  71.     ENDM
  72.  
  73.     MACRO                                ; Forces a RTS for MacsBug to accept it as a proc name
  74.     M_ProcNameRTS    &procedure_name
  75.     
  76.         STRING    PASCAL
  77.         rts
  78.         dc.b    $80, &procedure_name
  79.         ALIGN    2
  80.         dc.w    $0000
  81.     ENDM
  82.     
  83.     ELSE
  84.         MACRO
  85.         M_ProcName    &procedure_name
  86.         ENDM
  87.         MACRO
  88.         M_ProcNameRTS    &procedure_name
  89.         ENDM
  90.     ENDIF
  91.  
  92. WIDE_HI            EQU            0
  93. WIDE_LO            EQU            4
  94.  
  95. Wide_DivideU    PROC    EXPORT
  96. ;static void Wide_DivideU
  97. ;(
  98. ;    wide    *dividend_ptr,        /* in/out:  64 bits to be divided */
  99. ;    long     divisor,            /* in:      value to divide by */
  100. ;    long    *remainder_ptr        /* out:     the remainder of the division */
  101. ;)
  102.  
  103. DIVIDEND_PTR    EQU            8
  104. DIVISOR            EQU            12
  105. REMAINDER_PTR    EQU            16
  106.  
  107.         LINK    A6,#0
  108.         MOVEM.L D2-D7,-(SP)            ; save work registers
  109.         CLR.L    D0                    ;
  110.         CLR.L    D1                    ; D0-D1 is the quotient accumulator
  111.         MOVE.L    DIVIDEND_PTR(A6),A0    ;
  112.         MOVE.L    WIDE_HI(A0),D2      ;
  113.         MOVE.L    WIDE_LO(A0),D3      ; D2-D3 is the remainder accumulator
  114.         CLR.L    D4                    ;
  115.         MOVE.L    D2,D5                ; D5 = copy of dividend.hi
  116.         MOVE.L    DIVISOR(A6),D6        ; D6 = copy of divisor
  117.  
  118.         MOVEQ.L #31,D7                ; FOR number of bits in divisor (see @div99:)
  119. @divloop:
  120.         LSL.L   #1,D0               ; shift quotient.hi accumulator left once
  121.         LSL.L   #1,D1               ; shift quotient.lo accumulator left once
  122.         LSL.L    #1,D4                ;
  123.         LSL.L   #1,D3               ; shift remainder accumulator left once
  124.         BCC.S    @div29                ; IF CC, a zero bit shifted out
  125.         LSL.L   #1,D2               ;
  126.         BSET    #0,D2                ;
  127.         BRA.S    @div30
  128. @div29:
  129.         LSL.L   #1,D2               ;
  130. @div30:
  131.         SUB.L    D6,D2                ; remainder -= divisor
  132.         BCS.S    @div50                ; IF CS, remainder is negative
  133.         BSET    #0,D1                ; quotient.lo |= 1
  134.         BRA.S    @div77                ;
  135. @div50:
  136.         ADD.L    D6,D2                ; remainder += divisor
  137. @div77:
  138.         BTST    D7,D5                ;
  139.         BEQ.S    @div90                ; IF EQ, bit not set in dividend.hi
  140.         BSET    #0,D4                ;
  141. @div90:
  142.         CMP.L    D6,D4                ;
  143.         BCS.S    @div99                ; IF CS, divisor < D4
  144.         SUB.L    D6,D4                ; D4 -= divisor
  145.         BSET    #0,D0                ; quotient.hi |= 1
  146. @div99:
  147.         DBF        D7,@divloop            ; loop until D7 == -1
  148.  
  149.         MOVE.L    DIVIDEND_PTR(A6),A0 ; output the remainder
  150.         MOVE.L    D0,WIDE_HI(A0)      ;
  151.         MOVE.L    D1,WIDE_LO(A0)      ;
  152.         MOVE.L    REMAINDER_PTR(A6),A0    ; output the remainder
  153.         MOVE.L    D2,(A0)             ;
  154.         MOVEM.L (SP)+,D2-D7            ; restore work registers
  155.         UNLK    A6
  156.         RTS
  157.                 
  158.                 M_ProcName    'Wide_DivideU'    ;debugger information
  159.                 
  160.                 ENDP
  161.  
  162. Wide_DivS64        PROC    EXPORT
  163. ;static long Wide_DivS64
  164. ;(
  165. ;    const wide    *dividend_ptr,        /* in/out:  64 bits to be divided */
  166. ;    long         divisor,            /* in:      value to divide by */
  167. ;    long        *remainder_ptr,        /* out:     the remainder of the division */
  168. ;    short        *overflow_ptr        /* out:     flag indicating if overflow occured */
  169. ;)
  170. DIVIDEND_PTR    EQU            8
  171. DIVISOR            EQU            12
  172. REMAINDER_PTR    EQU            16
  173. OVERFLOW_PTR    EQU            20
  174.  
  175.         LINK    A6,#0
  176.         MOVE.L  D2,-(SP)
  177.         MOVEQ.L    #1,D2                    ; assume there is overflow
  178.         MOVE.L  DIVIDEND_PTR(A6),A0     ; A0 -> the dividend
  179.         MOVE.L    WIDE_LO(A0),D0            ;
  180.         MOVE.L    WIDE_HI(A0),D1            ; D1-D0 = 64 bit dividend
  181.         DC.W    $4C6E,$0C01,$000C        ; DIVS.L    DIVISOR(A6),D1-D0        - (64bit signed divide)
  182.         BVS.S    @divcont                ; IF VS, we're overflowed
  183.         CLR.W    D2                        ; ELSE, clear the overflow flag
  184. @divcont:
  185.         MOVE.L    REMAINDER_PTR(A6),A0    ; output remainder
  186.         MOVE.L    D1,(A0)                    ;
  187.         MOVE.L    OVERFLOW_PTR(A6),A0        ; output overflow flag
  188.         MOVE.W    D2,(A0)                    ;
  189.         MOVE.L  (SP)+,D2
  190.         UNLK    A6
  191.         RTS
  192.  
  193.                 M_ProcName    'Wide_DivS64'    ;debugger information
  194.                 
  195.                 ENDP
  196.  
  197. ;**********************************************************
  198.  
  199. Wide_MulS64        PROC    EXPORT
  200. ;static void Wide_MulS64
  201. ;(
  202. ;    long    multiplicand,        /* in:  first value to multiply */
  203. ;    long    multiplier,            /* in:  second value to multiply */
  204. ;    wide   *out_ptr                /* out: 64 bits to be assigned */
  205. ;)
  206.  
  207. MULTIPLICAND    EQU            8
  208. MULTIPLIER        EQU            12
  209. OUT_PTR            EQU            16
  210.  
  211.         LINK    A6,#0
  212.         MOVE.L  MULTIPLICAND(A6),D0     ;
  213.         DC.W    $4C2E,$0C01,$000C        ; MULS.L    MULTIPLIER(A6),D1-D0 - 64bit signed multiply
  214.         MOVE.L  OUT_PTR(A6),A0          ;
  215.         MOVE.L  D0,WIDE_LO(A0)          ; WIDE_LO defined earlier
  216.         MOVE.L  D1,WIDE_HI(A0)          ; WIDE_HI defined earlier
  217.         UNLK    A6
  218.         RTS
  219.  
  220.                 M_ProcName    'Wide_MulS64'    ;debugger information
  221.                 
  222.                 ENDP
  223.  
  224.                 END